package com.controller;

import com.orm.ServiceCalledEntity;
import com.orm.WebServiceEntity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by lirance on 16/5/4.
 */
public class Predict {


    public List<Integer> getSimilarUser(int uid, int k, int Gn) throws Exception { ///获取与uid前k个相似的用户id
        List<Sim> Sim = new ArrayList<>();
        List<Integer> simUsers = new ArrayList<>();
        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);
        List<ServiceCalledEntity> l = gsc.GetServiceCallLists();
        List ulist = new ArrayList<>();  //用户列表
        for (int i = 0; i < l.size(); i++) {  //获取调用了服务的用户
            if (!ulist.contains(l.get(i).getuId())) {
                ulist.add(l.get(i).getuId());
            }
        }


        for (int i = 1; i <= ulist.size(); i++) {
            Sim s = new Sim();
            s.setUserid1(uid);
            s.setUserid2(i);
            s.setGn(Gn);
            s.setSimlar();
            Sim.add(s);
        }
        //paixu

        for (int i = 0; i < Sim.size() - 1; i++) {
            for (int j = 1; j < Sim.size() - i; j++) {
                Sim a;
                if ((Sim.get(j - 1)).getSimlar() < (Sim.get(j).getSimlar())) { // 比较sim大小

                    a = Sim.get(j - 1);
                    Sim.set((j - 1), Sim.get(j));
                    Sim.set(j, a);
                }
            }
        }

        for (int i = 1; i <= k; i++) {
            simUsers.add(Sim.get(i).getUserid2());
        }
        return simUsers;
    }

    public double getPredicts(int uid, int sid, double lmd, int k, int Gn) throws Exception {
        double preRtt;
        Similarity similarity = new Similarity();
        double val_us, a = 0, b = 0;
        double sum = 0, num = 0;
        //AllService allService = new AllService();
        List<Integer> simUsers = getSimilarUser(uid, k, Gn);

        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);

        List<ServiceCalledEntity> list = gsc.GetServiceCallListsByuId(uid);//该用户调用的服务列表

        for (int i = 0; i < list.size(); i++) {
            sum = sum + list.get(i).getRtt() * list.get(i).getFrequency();
            num = num + list.get(i).getFrequency();
        }
        val_us = sum * 1.000 / num;   //该用户所有服务平均时间

        for (int i = 0; i < k; i++) {
            double sim = new Similarity().getSimilarity(uid, simUsers.get(i), Gn);
            if (sim == 0) break;
            if (!(similarity.getAverageVal(simUsers.get(i), sid, Gn) + "").equals("NaN")) {
                a = a + sim * similarity.getAverageVal(simUsers.get(i), sid, Gn);
            }
            b = b + sim;
        }

        preRtt = val_us * lmd * 1.000 + (1 - lmd) * a * 1.000 / b;
        return preRtt;
    }

    public double getPredicts_Cluster(int uid, int sid, double lmd, int k, int Gn) throws Exception {
        // new ClusterAnalysis().getClusterLists(clustNum);
        double preRtt = 0;
        Similarity similarity = new Similarity();
        double val_, a = 0, b = 0;
        double sum = 0, num = 0;
        List<Integer> simUsers = getSimilarUser(uid, k, Gn);

        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);

        List<ServiceCalledEntity> list = gsc.GetServiceCallListsByuId(uid);//用户调用的所有服务记录

        GetServiceList gss = new GetServiceList();
        //   GetServicesService gss = new GetServicesService();
        WebServiceEntity webService = (WebServiceEntity) gss.GetServiceListsBywsId(sid).get(0);
        String clusteNam = webService.getClusteNam();
        List<WebServiceEntity> serviceList = (List) (gss.GetServiceListsBywsclusteNam(clusteNam));//服务聚类中的服务

        List<Integer> shared = new ArrayList<>();

        for (int i = 0; i < serviceList.size(); i++) {
            for (int j = 0; j < list.size(); j++) {
                if (serviceList.get(i).getWsId() == list.get(j).getWsId()) {
                    shared.add(serviceList.get(i).getWsId()); //交集
                    break;
                }
            }
        }


        double sum1 = 0;

        if (shared.size() < 2) {//聚类没有的话
            for (int i = 0; i < serviceList.size(); i++) {
                sum1 = sum1 + Double.parseDouble(serviceList.get(i).getClusteNum());
            }
            val_ = sum1 * 1.000 / serviceList.size();
        } else {//如果类里还有其他的

            List<WebServiceEntity> list1 = new ArrayList<>();
            for (int i = 0; i < shared.size(); i++) {
                list1.add((WebServiceEntity) ((List) gss.GetServiceListsBywsId(shared.get(i))).get(0));
            }
            for (int i = 0; i < list1.size(); i++) {
                sum1 = sum1 + Double.parseDouble(list1.get(i).getClusteNum());
            }
            val_ = sum1 * 1.000 / list1.size();
        }


        for (int i = 0; i < list.size(); i++) {
            sum = sum + list.get(i).getRtt() * list.get(i).getFrequency();
            num = num + list.get(i).getFrequency();
        }
        //  val_us = sum * 1.000 / num;   //该用户所有服务平均时间

        for (int i = 0; i < k; i++) {
            double sim = similarity.getSimilarity(uid, simUsers.get(i), Gn);
            if (sim == 0) break;
            if (!(similarity.getAverageVal(simUsers.get(i), sid, Gn) + "").equals("NaN")) {
                a = a + sim * similarity.getAverageVal(simUsers.get(i), sid, Gn);
            }
            b = b + sim;
        }

        preRtt = val_ * lmd * 1.000 + (1 - lmd) * a * 1.000 / b;
        return preRtt;
    }
}
